

let Vue

class Store {
    constructor(options){
        // console.log(options)
        this._mutations = options.mutations
        this._actions = options.actions
        this._wrappedGetters = options.getters || {}

        // 定义computed
        const computed = {}
        this.getters = {}
        // console.log(this.getters,computed,this._wrappedGetters)
        const store = this
        Object.keys(this._wrappedGetters).forEach(key => {
            // 获取用户定义的getter
            const fn = store._wrappedGetters[key]
            // 转换为computed可以使用的无参数形式
            computed[key] = function(){
                return fn(store.state)
            }
            Object.defineProperty(store.getters,key,{
                get:()=> store._vm[key]
            })
        });

        // 响应式处理数据
        this._vm = new Vue({
            data: {
                // 添加两个$$不会被vue代理
                $$state: options.state
            },
            computed
        })

        // 重新指向this
        this.commit = this.commit.bind(this)
        this.dispatch = this.dispatch.bind(this)
    }

    // 做一个代理
    get state() {
        return this._vm._data.$$state
    }

    set state(v){
        console.error('请使用replaceState重置状态');
    }

    commit(type,payload){
        // 找到对应的type
        const mutations = this._mutations[type]
        if (!mutations) {
            console.error('mutation不存在')
            return
        }
        // 执行调用 payload 为第二个入参可修改对应state的值
        mutations(this.state,payload)
    }

    dispatch(type,payload) {
        const actions = this._actions[type]
        if(!actions) {
            console.error('actions不存在')
            return
        }
        actions(this,payload)
    }
}


function install(_Vue) {
    Vue = _Vue

    // 注册 store
    Vue.mixin({
        beforeCreate() {
            if (this.$options.store) {
                Vue.prototype.$store = this.$options.store
            }
        }
    })
}


export default { Store , install };